package deployr.client.http;

import static java.text.MessageFormat.*;

import java.io.*;
import java.net.*;

import deployr.client.api.*;

public class UpdateHttpClient implements UpdateApi {

	@Override
	public void createDeliverable(String deployrUrl, String updateKey, String name, String uri, String md5) {
		boolean created = tryCreateDeliverable(deployrUrl, updateKey, name, uri, md5);
		if(!created) created = tryCreateDeliverable(deployrUrl, updateKey, name, uri, md5);
		if(!created) created = tryCreateDeliverable(deployrUrl, updateKey, name, uri, md5);
		if(created) return;
		
		throw new RuntimeException(format("problem uploading {0}", name));
	}

	private boolean tryCreateDeliverable(String deployrUrl, String updateKey, String name, String uri, String md5) {
		try {
			StringBuilder data = new StringBuilder();
			data.append("name").append("=").append(URLEncoder.encode(name, "UTF-8")).append("&");
			data.append("uri").append("=").append(URLEncoder.encode(uri, "UTF-8")).append("&");
			data.append("md5").append("=").append(URLEncoder.encode(md5, "UTF-8")).append("&");

			URL url = new URL(format("{0}/updates/{1}/files", deployrUrl, updateKey));
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setRequestMethod("POST");
			connection.setUseCaches(false);
			connection.setDoInput(true);
			connection.setDoOutput(true);

			OutputStream outputStream = connection.getOutputStream();
			outputStream.write(data.toString().getBytes());

			int status = connection.getResponseCode();

			return 200 == status;
		} catch (Exception e) {
			return false;
		}
	}

	@Override
	public int createEvent(String deployrUrl, String updateKey, String event) {
		try {
			StringBuilder data = new StringBuilder();
			data.append("event").append("=").append(URLEncoder.encode(event, "UTF-8")).append("&");

			URL url = new URL(format("{0}/updates/{1}/events", deployrUrl, updateKey));
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setRequestMethod("POST");
			connection.setUseCaches(false);
			connection.setDoInput(true);
			connection.setDoOutput(true);

			OutputStream outputStream = connection.getOutputStream();
			outputStream.write(data.toString().getBytes());
			int status = connection.getResponseCode();
			if (404 == status) throw new RuntimeException("update " + updateKey + " not found");
			return status;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void updatechecksum(String deployrUrl, String updateKey, String checksum) {
		try {
			StringBuilder data = new StringBuilder();
			data.append("checksum").append("=").append(URLEncoder.encode(checksum, "UTF-8")).append("&");

			URL url = new URL(format("{0}/updates/{1}/checksum", deployrUrl, updateKey));
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setRequestMethod("POST");
			connection.setUseCaches(false);
			connection.setDoInput(true);
			connection.setDoOutput(true);

			OutputStream outputStream = connection.getOutputStream();
			outputStream.write(data.toString().getBytes());
			int status = connection.getResponseCode();
			if (404 == status) throw new RuntimeException("update " + updateKey + " not found");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void updateDiff(String deployrUrl, String updateKey, String diff) {
		try {
			StringBuilder data = new StringBuilder();
			data.append("diff").append("=").append(URLEncoder.encode(diff, "UTF-8")).append("&");

			URL url = new URL(format("{0}/updates/{1}/diff", deployrUrl, updateKey));
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setRequestMethod("POST");
			connection.setUseCaches(false);
			connection.setDoInput(true);
			connection.setDoOutput(true);

			OutputStream outputStream = connection.getOutputStream();
			outputStream.write(data.toString().getBytes());
			int status = connection.getResponseCode();
			if (404 == status) throw new RuntimeException("update " + updateKey + " not found");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

}